<?php

/**
 * Default User Interface Component
 *
 */
 
class UIComponent {
	/**
	 * Component properties
	 */
	protected $properties;
	
	/**
	 * Parent component (container)
	 */
	protected $parent;

	/**
	 * Default Constructor
	 */
	public function __construct($id='', $parent=null) {
		$this->properties = array();
		$this->registerProperties('id', 'title', 'tooltip', 'renderer');
		
		// initialize properties
		$this->id 		= $id;
		$this->parent 	= $parent;
		$this->tooltip 	= null;
		$this->renderer = null;
	}
	
	/**
	 * Registers the specified properties for this component
	 */
	protected function registerProperties() {
		$props = func_get_args();
		foreach ($props as $prop)
			if ( !array_key_exists($prop, $this->properties) )
				$this->properties[$prop] = $value;
	}
	
	/**
	 * Changes the values of a set of properties.
	 *
	 * @param mixed properties the properties to be updated. This function may have one of the following formats: a. associative array b. non-associative array and c. a list of parameters (ex. 'label', 'hello', 'world', '!')
	 */
	public function setProperties($properties) {
		$numArgs = func_num_args();
		if ( $numArgs == 1 && is_array($properties) ) {
			if ( is_associative($properties) ) {
				$this->properties = array_merge($this->properties, $properties);
			} else {
				for ( $i=0; $i<count($properties); $i+=2 ) {
					$this->properties[$properties[$i]] = $properties[($i+1)];
				}				
			}
		} else if ( $numArgs > 1 ) {
			for ( $i=0; $i<$numArgs; $i+=2 ) {
				$this->properties[func_get_arg($i)] = func_get_arg(($i+1));
			}	
		}
	}
	
	/**
	 * Returns the parent component (container) of this component. Returns null if this component does not have a parent. See hasParent
	 */
	public function getParent() {
		return ( $this->parent );
	}
	
	/**
	 * Sets a new parent for this component
	 */
	public function setParent($parent) {
		$this->parent = $parent;
	}	
	
	/**
	 * Returns true if this component does not have a parent
	 */
	public function hasParent() {
		return ( $this->parent != null );
	}
	
	/**
	 * Sets a new value for the specified property.
	 * 
	 * @param string name the property name
	 * @param mixed value the corresponding value
	 */
	public function __set($name, $value) {
		$this->properties[$name] = $value;
	}
	
	/**
	 * Returns the value of the specified property
	 *
	 * @param string name the property name
	 */
	public function __get($name) {
		if ( $name == 'id' ) {
			if ( empty($this->properties['id']) && !empty($this->properties['title']) ) {
				Cinnamon::loadClass('Text');	
				$id = strip_tags($this->title);
				$id = preg_replace('/&[a-zA-Z#0-9]+;/', '', $id);
				$id = Text::camelize($id);
			} else {
				$id = $this->properties['id'];
			}
			
			if ( $this->hasParent() && get_class($this->getParent) != 'View' )
				$id = $this->getParent()->id . $id;
			return $id;
		}
		return $this->properties[$name];
	}	
	
	/**
	 * Renders this component
	 */
	public function render() {
		$this->dispatchRenderEvent();
		$this->_render();
	}
	protected function _render() {
		$file = CSEPATH . $this->renderer;
		if ( preg_match('/(\.html|\.html|\.php)$/', $file) && file_exists($file) ) 
			include $file;
		else if ( function_exists($this->renderer) )
			call_user_func($this->renderer);
	}
	
	/**
	 * Dispatches fire event for this user interface instance
	 */
	protected function dispatchRenderEvent() {
		$evt = new Event( get_class($this), 'instance', $this );
		Cinnamon::registry('events')->dispatchEvent($evt);
	}
}

?>